package com.odontosis.view.servico;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.util.LabelValueBean;

import com.odontosis.entidade.Convenio;
import com.odontosis.entidade.OdontosisBusinessObject;
import com.odontosis.entidade.Paciente;
import com.odontosis.entidade.Pagamento;
import com.odontosis.entidade.Procedimento;
import com.odontosis.entidade.Servico;
import com.odontosis.entidade.StatusServico;
import com.odontosis.entidade.TipoServico;
import com.odontosis.ioc.ContainerIoc;
import com.odontosis.service.PacienteService;
import com.odontosis.service.PagamentoService;
import com.odontosis.service.ServicoService;
import com.odontosis.util.StringUtilsOdontosis;
import com.odontosis.view.OdontosisCadastroForm;
import com.odontosis.view.OdontosisForm;

/**
 * Formulrio de cadastro de servios.
 * @author Oto
 */
public class FormCadastroServico extends OdontosisCadastroForm {
	private static final long serialVersionUID = -2856885293407967884L;

	private String descricao;
	private String pacienteNome;
	private String valor;
	private String quantidadeParcelas;
	private String tipo = "0";
	private String mesVencimentoPrimeiraParcela;
	private String anoVencimentoPrimeiraParcela;
	private String paciente;
	private String valorInicial;
	private String quantidadeInicial="6";
	private String alteracao;
	private String convenio;
	private String procedimento;
	private String status;
	private String  idProcedimento;
	private boolean isentar;
	private List<Paciente> colecaoPacientes;
	private List<Procedimento> procedimentos = new ArrayList<Procedimento>();
	private List<Procedimento> colecaoProcedimentos;
	public List<String> erros;
	private boolean orcamento = false;
	public boolean isentarAgora = false;
	
	private String mesIsencao ; //= new Integer(Calendar.getInstance().get(Calendar.MONTH) + 1).toString();
	private String anoIsencao ; //= new Integer(Calendar.getInstance().get(Calendar.YEAR)).toString();
	
	
	public String getMesIsencao() {
		return mesIsencao;
	}

	public String getAnoIsencao() {
		return anoIsencao;
	}

	public void setMesIsencao(String mesIsencao) {
		this.mesIsencao = mesIsencao;
	}

	public void setAnoIsencao(String anoIsencao) {
		this.anoIsencao = anoIsencao;
	}

	public Collection<String> getErros(){
		if(erros == null){
			return new ArrayList<String>();
		}
		return erros;
	}

	public void setErros(List<String> erros) {
		this.erros = erros;
	}
	
	public List<Paciente> getColecaoPacientes() throws Exception{
		PacienteService pacienteService = new PacienteService();
		colecaoPacientes = pacienteService.buscarPacienteEmTratamentoOuEmAcompanhamento();
		
		return  colecaoPacientes;
	}
	
	public Convenio[] getColecaoConvenios() throws Exception{
		return Convenio.values();
	}
	
	public StatusServico[] getVetorStatusServico() {
		return StatusServico.values();
	}
	
	
	public List<Procedimento> getColecaoProcedimentos() {
		try{
			colecaoProcedimentos = ContainerIoc.getProcedimentoService().findAll();
		}catch (Exception e) {
		}
		return colecaoProcedimentos;
	}

	public void setColecaoProcedimentos(List<Procedimento> colecaoProcedimentos) {
		this.colecaoProcedimentos = colecaoProcedimentos;
	}

	/**
	 * @return the valor
	 */
	public String getValor() {
		return valor;
	}
	/**
	 * @param valor the valor to set
	 */
	public void setValor(String valor) {
		this.valor = valor;
	}
	/**
	 * @return the quantidadeParcelas
	 */
	public String getQuantidadeParcelas() {
		return quantidadeParcelas;
	}
	/**
	 * @param quantidadeParcelas the quantidadeParcelas to set
	 */
	public void setQuantidadeParcelas(String quantidadeParcelas) {
		this.quantidadeParcelas = quantidadeParcelas;
	}
	/**
	 * @return the tipo
	 */
	public String getTipo() {
		return tipo;
	}
	/**
	 * @param tipo the tipo to set
	 */
	public void setTipo(String tipo) {
		this.tipo = tipo;
	}
	/**
	 * @return the mesVencimentoPrimeiraParcela
	 */
	public String getMesVencimentoPrimeiraParcela() {
		return mesVencimentoPrimeiraParcela;
	}
	/**
	 * @param mesVencimentoPrimeiraParcela the mesVencimentoPrimeiraParcela to set
	 */
	public void setMesVencimentoPrimeiraParcela(String mesVencimentoPrimeiraParcela) {
		this.mesVencimentoPrimeiraParcela = mesVencimentoPrimeiraParcela;
	}
	/**
	 * @return the anoVencimentoPrimeiraParcela
	 */
	public String getAnoVencimentoPrimeiraParcela() {
		return anoVencimentoPrimeiraParcela;
	}
	/**
	 * @param anoVencimentoPrimeiraParcela the anoVencimentoPrimeiraParcela to set
	 */
	public void setAnoVencimentoPrimeiraParcela(String anoVencimentoPrimeira) {
		this.anoVencimentoPrimeiraParcela = anoVencimentoPrimeira;
	}
	/**
	 * @return the paciente
	 */
	public String getPaciente() {
		return paciente;
	}
	/**
	 * @param paciente the paciente to set
	 */
	public void setPaciente(String paciente) {
		this.paciente = paciente;
	}
	public String getDescricao() {
		return descricao;
	}
	public void setDescricao(String descricao) {
		this.descricao = descricao;
	}
	
	public void resetar(){
		this.anoVencimentoPrimeiraParcela = null;
		this.descricao = null;
		this.mesVencimentoPrimeiraParcela = null;
		this.paciente = null;
		this.quantidadeParcelas = null;
		this.tipo = null;
		this.valor = null;
		this.pacienteNome = "";
		this.isentar = false;
		this.convenio = "";
		
	}

	@Override
	public ActionErrors validate(ActionMapping mapping,
			HttpServletRequest request) {
		
		
		ActionErrors errors = new ActionErrors();
		ActionMessages messages = new ActionMessages();
		if(!StringUtilsOdontosis.isVazia(getMetodo()) && getMetodo().equals("editar") && isIsentar()){
			Servico servico = null;
			try{
				servico = ContainerIoc.getServicoService().load(Long.parseLong(getAlteracao()));	
			}catch (Exception e) {
				throw new IllegalArgumentException("Erro na criação de serviço");
			}
			
			if(StringUtilsOdontosis.isVazia(getMesIsencao()) || StringUtilsOdontosis.isVazia(getAnoIsencao())){	
				messages.add("mes",new ActionMessage("O campo Mês/Ano da Isenção é obrigatório"));
			}else{
				int mes = Integer.parseInt(getMesIsencao());
				int ano = Integer.parseInt(getAnoIsencao());
				if(mes<1 || mes > 12){
					messages.add("mes",new ActionMessage("O campo Mês/Ano da Isenção é inválido"));
				}
				
				if(ano < 1985 || ano > 3000) {
					messages.add("mes",new ActionMessage("O campo Ano da Isenção difere de maneira anormal do ano Atual, verifique o ano digitado ou a configuração de data do Servidor."));
				}
			}
			
			if(messages.size() <= 0 && isentar){
				isentarAgora = true;
				servico.setMesIsencao(Integer.parseInt(getMesIsencao()));
				servico.setAnoIsencao(Integer.parseInt(getAnoIsencao()));
			}else{
				isentarAgora = false;
			}
			try{
				transferirParaForm(this, servico);
			}catch (Exception e) {
				throw new IllegalArgumentException("Erro na validação de serviço");
			}
			
		}
		if(!StringUtilsOdontosis.isVazia(getMetodo()) && !getMetodo().equals("add") && !getMetodo().equals("editar")){
			//faz a isenção
			if(isIsentar()){
				if(StringUtilsOdontosis.isVazia(getMesIsencao()) || StringUtilsOdontosis.isVazia(getAnoIsencao())){
					messages.add("mes",new ActionMessage("O campo Mês/Ano da Isenção é obrigatório."));
				}else{
					int mes = Integer.parseInt(getMesIsencao());
					if(mes<1 || mes > 12){
						messages.add("mes",new ActionMessage("O campo Mês/Ano da Isenção é inválido."));
					}
				}
				
				if(messages.size() <= 0){
					isentarAgora = true;
				}
				
			}
			
			
			if (StringUtilsOdontosis.isVazia(getPaciente())) {
				messages.add("paciente",
						new ActionMessage("O campo Paciente é obrigatório."));
			}
			if (StringUtilsOdontosis.isVazia(getTipo())) {
				messages.add("tipoServico", new ActionMessage(
						"O campo Tipo de Serviço é obrigatório."));
			}
			if(StringUtilsOdontosis.isVazia(getMesVencimentoPrimeiraParcela()) || StringUtilsOdontosis.isVazia(getAnoVencimentoPrimeiraParcela())){
				messages.add("anoVencimentoPrimeiraParcela", new ActionMessage(
								"O campo Mês/Ano da primeira parcela é obrigatório."));
			}else{
				try{
					int mes = Integer.parseInt(getMesVencimentoPrimeiraParcela());
					int ano = Integer.parseInt(getAnoVencimentoPrimeiraParcela());
					if(mes > 12 || mes <= 0){
						messages.add("anoVencimentoPrimeiraParcela", new ActionMessage(
										"O campo Mês/Ano da primeira parcela é inválido."));
					}
					
					if(ano < 1985 || ano > 2100) {
						messages.add("mes",new ActionMessage("O campo Ano da primeira parcela difere de maneira anormal do ano Atual, verifique o ano digitado ou a configuração de data do Servidor."));
					}
					
				}catch (Exception e) {
					messages.add("anoVencimentoPrimeiraParcela", new ActionMessage(
					"O campo Mês/Ano primeira parcela é inválido."));
				}
			}
			
			
			//validação individual por tipo de serviço
			if(!StringUtilsOdontosis.isVazia(getTipo())){
				TipoServico tipoServico = TipoServico.recuperarPorId(Integer.parseInt(getTipo())); 
				if(!(tipoServico == TipoServico.MANUTENCAO) && StringUtilsOdontosis.isVazia(getQuantidadeParcelas())){
					messages.add("quantidadeParcelas", new ActionMessage(
											"O campo Quantidade de Parcelas é obrigatório."));
				}
				//retirada a obrigatoriedade das parcelas iniciais
//				if(	(tipoServico == TipoServico.MANUTENCAO) && StringUtilsOdontosis.isVazia(getValorInicial())){
//					messages.add("valorInicial", new ActionMessage(
//						"O campo Valor das parcelas inciais é obrigatório."));
//				}
//				
//				if(	(tipoServico == TipoServico.MANUTENCAO) && StringUtilsOdontosis.isVazia(getQuantidadeInicial())){
//					messages.add("valorInicial", new ActionMessage(
//						"O campo Quantidade das parcelas inciais é obrigatório."));
//				}
				
				if(	 StringUtilsOdontosis.isVazia(getValor())){
					if (tipoServico == TipoServico.MANUTENCAO) {
						messages.add("valor", new ActionMessage(
										"O campo Valor Mensal é obrigatório."));
					}else{
						messages.add("valor", new ActionMessage(
						"O campo Valor é obrigatório."));
					}
				}
				
				
			}
			
			
			//validação para alteração de serviço
			if(!StringUtilsOdontosis.isVazia(getAlteracao()) && (
					!StringUtilsOdontosis.isVazia(getMetodo()) && !getMetodo().equals("isentar"))){
				
				try{
					ServicoService servicoService = ContainerIoc.getServicoService();
					Servico servico = servicoService.load(Long.parseLong(getAlteracao()));
					for(Pagamento pagamento:servico.getListaPagamentos()){
						
						if((pagamento.getListaRecibos().size() > 0 )){
							messages.add("valor", new ActionMessage(
									"O Serviço já possui pagamentos efetuados, portanto não pode ser alterado."));
							break;
						}
					}
					
					
				}catch (Exception e) {
					e.printStackTrace();
				}
				
			
			}
			
		}
		if (messages.size() > 0 && getMetodo() != null) {
			errors.add(messages);
			erros = new ArrayList<String>();
			for (Iterator iterator = messages.get(); iterator.hasNext();) {
				ActionMessage string = (ActionMessage) iterator.next();
				erros.add(string.getKey());
			}
			request.setAttribute("mensagens", erros);
			return errors;
		} else {
			request.setAttribute("mensagens", null);
			return super.validate(mapping, request);
		}
	}
	
	
	public TipoServico[] getTiposServico(){
		TipoServico[] tiposServico = TipoServico.values();
		List<LabelValueBean> valueBeans = new ArrayList<LabelValueBean>();
		for (TipoServico tipoServico : tiposServico) {
			valueBeans.add(new LabelValueBean(
			tipoServico.getDescricao(),
			String.valueOf(tipoServico.getId())));
		}
		return tiposServico;
	}

	public String getValorInicial() {
		return valorInicial;
	}

	public void setValorInicial(String valorPrimeirasParcelas) {
		this.valorInicial = valorPrimeirasParcelas;
	}

	public String getQuantidadeInicial() {
		return quantidadeInicial;
	}

	public void setQuantidadeInicial(String quantidadePrimeirasParcelas) {
		this.quantidadeInicial = quantidadePrimeirasParcelas;
	}

	public void setColecaoPacientes(List<Paciente> colecaoPacientes) {
		this.colecaoPacientes = colecaoPacientes;
	}

	public String getAlteracao() {
		return alteracao;
	}

	public void setAlteracao(String servicoAnterior) {
		this.alteracao = servicoAnterior;
	}

	public String getPacienteNome() {
		return pacienteNome;
	}

	public void setPacienteNome(String pacienteNome) {
		this.pacienteNome = pacienteNome;
	}

	public boolean isIsentar() {
		return isentar;
	}

	public void setIsentar(boolean isentar) {
		this.isentar = isentar;
	}
	
	public String getConvenio() {
		return convenio;
	}

	public void setConvenio(String convenio) {
		this.convenio = convenio;
	}

	public boolean getLinkIsentar(){
		if(isentar){
			return false;
		}
		if(StringUtilsOdontosis.isVazia(getAlteracao())){
			return false;
		}
		return true;
	}
	
	public boolean getHabilitaIsentar(){
		if(StringUtilsOdontosis.isVazia(getAlteracao())){
			return true;
		}
		return false;
	}
	
	public boolean isSalvo(){
		if(StringUtilsOdontosis.isVazia(getAlteracao())){
			return false;
		}
		return true;
	}

	public boolean isIsentarAgora() {
		return isentarAgora;
	}

	public void setIsentarAgora(boolean isentarAgora) {
		this.isentarAgora = isentarAgora;
	}

	public List<Procedimento> getProcedimentos() {
		return procedimentos;
	}

	public void setProcedimentos(List<Procedimento> procedimentos) {
		this.procedimentos = procedimentos;
	}

	public String getProcedimento() {
		return procedimento;
	}

	public void setProcedimento(String procedimento) {
		this.procedimento = procedimento;
	}

	public boolean isOrcamento() {
		return orcamento;
	}

	public void setOrcamento(boolean orcamento) {
		this.orcamento = orcamento;
	}

	@Override
	public void transferirParaForm(OdontosisForm form,
			OdontosisBusinessObject... businessObjects)
			throws IllegalAccessException, InvocationTargetException {
		super.transferirParaForm(form, businessObjects);
		FormCadastroServico formC = (FormCadastroServico) form; 
		for(OdontosisBusinessObject odonto: businessObjects){
			Servico servico = (Servico) odonto;
			formC.setMesIsencao(servico.getMesIsencao().toString());
			formC.setAnoIsencao(servico.getAnoIsencao().toString());
			formC.setIsentar(servico.isIsento());
		}
	}

	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}
	
	
	
	
	/**
	 * Transfere para Business Objects.
	 * @param form Formulrio.
	 * @param businessObjects busiess Objects.
	 */
//	@Override
//	public void transferirParaBOs(OdontosisForm form,
//			OdontosisBusinessObject... businessObjects)
//			throws IllegalAccessException, InvocationTargetException {
//		
//		FormCadastroServico formCadastroServico = (FormCadastroServico)form;
//		Servico servico = (Servico)businessObjects[0];
//		
//		servico.setPago(false);
//		servico.setDescricao(formCadastroServico.getDescricao());
//		servico.setValor(new BigDecimal(formCadastroServico.getValor()));
//		servico.setQuantidadeParcelas(Integer.valueOf(formCadastroServico.getQuantidadeParcelas()));
//		servico.setTipo(TipoServico.recuperarPorId(Integer.valueOf(formCadastroServico.getTipo())));
//		servico.setMesVencimentoPrimeiraParcela(Integer.valueOf(formCadastroServico.getMesVencimentoPrimeiraParcela()));
//		servico.setAnoVencimentoPrimeiraParcela(Integer.valueOf(formCadastroServico.getAnoVencimentoPrimeiraParcela()));
//		
//		EntityManager entityManager = ServiceLocator.getEntityManager(Constantes.PERSISTENCE_UNIT);
//		PacienteDAO pacienteDAO = new PacienteDAO();
//		Paciente paciente = pacienteDAO.recuperarPorId(Long.valueOf(formCadastroServico.getPaciente()), entityManager);
//		
//		servico.setPaciente(paciente);
//	}
}
